import 'dart:async';

import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:libflutter/bean/ChatSession.dart';
import 'package:libflutter/logger/logger.dart';
import 'package:libflutter/net/RDApi.dart';

final configProvider = FutureProvider<String>((ref) async {
  return "进行网络请求，异步刷新数据 >>> ${DateTime.now().toLocal()}";
});

class TestRiverpodWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ProviderScope(child: _MApp());
  }
}

class _MApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    /// 这里刷新两次 TODO 需要求证是否有漏洞
    var watch = ref.watch(configProvider);
    Logcat.E("_MAppState ${watch}");
    return Scaffold(
      appBar: AppBar(
        title: const Text("Riverpod"),
      ),
      body: SingleChildScrollView(
        scrollDirection: Axis.vertical,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text("  测试 FuturnProvider"),
            TestFuturnProvider(),
            Text("\n  测试 Listen 和 listenManual"),
            TestListenProvider(),
            Text("\n  测试 Provider StateNotifierProvider"),
            ProviderWidget(),
            Text("\n  测试 StateProvider"),
            PageWidget(),
            Text("\n  测试 StateProvider 优化"),
            PageWidget2(),
            Text("\n  测试 AsyncNotifierProvider 异步"),
            _TextAsyncNotifierProvider(),
            Text("\n  测试 _TextAsyncNotifier2Provider 异步 无需重新加载界面"),
            _TextAsyncNotifier2Provider()
          ],
        ),
      ),
    );
  }
}

///------------------------------------------------------------------------------------------------

class TestFuturnProvider extends ConsumerStatefulWidget {
  @override
  ConsumerState<ConsumerStatefulWidget> createState() {
    return _TestFuturnProviderState();
  }
}

class _TestFuturnProviderState extends ConsumerState<TestFuturnProvider> {
  @override
  Widget build(BuildContext context) {
    return TextButton(
        onPressed: () {
          Logcat.E("进行请求数据刷新");

          /// 不需要返回结果 ，只进行数据刷新，界面更新，让watch的widget进行刷新即可
          ref.invalidate(configProvider);

          /// 需要返回值
          // ref.refresh(configProvider.future).then((value)  {
          //   Logcat.E("_TestFuturnProviderState ${value}");
          // });
        },
        child: Text("asdasda"));
  }
}

///------------------------------------------------------------------------------------------------

class TestListenProvider extends ConsumerStatefulWidget {
  @override
  ConsumerState<ConsumerStatefulWidget> createState() {
    return _TestListenProviderState();
  }
}

class _TestListenProviderState extends ConsumerState<TestListenProvider> {
  @override
  void initState() {
    super.initState();
    ref.listenManual(configProvider, (previous, next) {
      Logcat.E("_TestListenProviderState listenManual \nprevious=${previous} \nnext=${next}");
    });
  }

  String _value = "";

  @override
  Widget build(BuildContext context) {
    ref.listen(configProvider, (previous, next) {
      Logcat.E("_TestListenProviderState listen \nprevious=${previous} \nnext=${next}");
      setState(() {
        _value = next.asData?.value ?? "-";
      });
    });
    return TextButton(onPressed: () {}, child: Text("ListenProvider $_value"));
  }
}

/// 学习使用其provider ------------------------------------------------------------------------------
class Todo {
  final bool isCompleted;

  final String description;

  Todo(this.isCompleted, this.description);
}

class TodosNotifier extends StateNotifier<List<Todo>> {
  TodosNotifier() : super([]);

  addTodo(Todo todo) {
    state = [...state, todo];
  }
}

//这个可以进行一些操作
final todosProvider = StateNotifierProvider<TodosNotifier, List<Todo>>((ref) => TodosNotifier());

final completedTodosProvider = Provider<List<Todo>>((ref) {
  final todos = ref.watch(todosProvider);
  return todos.where((element) => element.isCompleted).toList();
});

class ProviderWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Column(
      children: [
        Consumer(builder: (context, ref, child) {
          var watch = ref.watch(completedTodosProvider);
          return Text(" Todos count ${watch.length}");
        }),
        TextButton(
            onPressed: () {
              ref
                  .read(todosProvider.notifier)
                  .addTodo(Todo(true, DateTime.now().toLocal().toString()));
            },
            child: const Text("Add Todo"))
      ],
    );
  }
}

// 也能进行简单的操作，只不过比较 StateNotifierProvider 使用起来有限制
// StateProvider 的 更新state是自身  而StateNotifierProvider的state来源于StateNotifier
final pageIndexProvider = StateProvider((ref) => 0);

class PageWidget extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    /// 这样有个缺点 就是当处于1-9的时候 根本不需要进行构建 ，但页进行widget
    var watch = ref.watch(pageIndexProvider);
    void prev() {
      ref.read(pageIndexProvider.notifier).update((state) => state - 1);
    }

    void next() {
      ref.read(pageIndexProvider.notifier).update((state) => state + 1);
    }

    return Row(
      children: [
        TextButton(onPressed: watch <= 0 ? null : prev, child: const Text("上一页")),
        Text("当前：$watch"),
        TextButton(onPressed: watch >= 10 ? null : next, child: const Text("下一页")),
      ],
    );
  }
}

final canPrev = Provider<bool>((ref) {
  return ref.watch(pageIndexProvider) > 0;
});
final canNext = Provider<bool>((ref) {
  return ref.watch(pageIndexProvider) < 10;
});

///优化
class PageWidget2 extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    Logcat.E(" PageWidget2 >> 开始构建");

    /// 这样有个缺点 就是当处于1-9的时候 根本不需要进行构建 ，但页进行widget
    ref.listen(pageIndexProvider.notifier, (previous, next) {
      Logcat.E(" PageWidget2 >>监听  $previous - $next");
    });
    void prev() {
      ref.read(pageIndexProvider.notifier).update((state) => state - 1);
    }

    void next() {
      ref.read(pageIndexProvider.notifier).update((state) => state + 1);
    }

    return Row(
      children: [
        TextButton(onPressed: ref.watch(canPrev) ? prev : null, child: const Text("上一页")),
        TextButton(onPressed: ref.watch(canNext) ? next : null, child: const Text("下一页")),
      ],
    );
  }
}

/// 异步notice
class ChatSessionListProvider extends AsyncNotifier<List<ChatSession>> {
  /// 初次构建需要提供一个默认的数据填充 build
  /// 这里进行一个开发 对话框的开发任务
  int _page = 1;
  int _position = 0;

  @override
  FutureOr<List<ChatSession>> build() {
    return getSessionByPage();
  }

  Future<void> refresh(void Function()? onRefresh) async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async {
      try {
        return getSessionByPage();
      } finally {
        onRefresh?.call();
      }
    });
  }

  Future<void> loadMore(void Function()? onLoadMore) async {
    state = const AsyncValue.loading();
    state = await AsyncValue.guard(() async {
      try {
        return getSessionByPage(page: _page + 1);
      } finally {
        onLoadMore?.call();
      }
    });
  }

  // 获取第一页的对话框
  Future<List<ChatSession>> getSessionByPage({int page = 1}) async {
    _page = page;
    _position = page * 20;
    return await Future.delayed(const Duration(seconds: 1), () {
      const pageSize = 20;
      var result = <ChatSession>[];
      for (var idx = 0; idx < pageSize * page; idx++) {
        result.add(ChatSession(idx, "$idx >>> Session"));
      }
      return result;
    });
  }
}

final chatSessionProvider = AsyncNotifierProvider<ChatSessionListProvider, List<ChatSession>>(
        () => ChatSessionListProvider());

class _TextAsyncNotifierProvider extends ConsumerStatefulWidget {
  @override
  ConsumerState<ConsumerStatefulWidget> createState() {
    return _AsyncState();
  }
}

class _AsyncState extends ConsumerState<_TextAsyncNotifierProvider> {
  final _refreshController = EasyRefreshController(
    controlFinishLoad: true,
    controlFinishRefresh: true,
  );

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final asyncSession = ref.watch(chatSessionProvider);
    return ConstrainedBox(
        constraints: const BoxConstraints(
          minWidth: double.infinity, //宽度尽可能大
          minHeight: 200.0, //最小高度为50像素
          maxHeight: 200,
        ),
        child: asyncSession.when(
          data: (sessions) {
            return EasyRefresh(
              controller: _refreshController,
              header: const ClassicHeader(),
              footer: const ClassicFooter(),
              onRefresh: () {
                final notifier = ref.read(chatSessionProvider.notifier);
                notifier.refresh(() {
                  _refreshController.finishRefresh();
                  Fluttertoast.showToast(msg: "上拉刷新--完成");
                });
              },
              onLoad: () async {
                final notifier = ref.read(chatSessionProvider.notifier);
                notifier.loadMore(() {
                  _refreshController.finishLoad();
                  Fluttertoast.showToast(msg: "下拉加载--完成");
                });
              },
              child: ListView.builder(
                  itemExtent: 50,
                  itemCount: sessions.length,
                  itemBuilder: (BuildContext context, int index) {
                    final item = sessions[index];
                    return Text(item.toString());
                  }),
            );
          },
          error: (err, stack) => Text('Error: $err'),
          loading: () =>
          const Center(
            child: CircularProgressIndicator(),
          ),
        ));
  }
}

/// 异步notice
class ChatSessionList2Provider extends AsyncNotifier<List<ChatSession>> {
  /// 初次构建需要提供一个默认的数据填充 build
  /// 这里进行一个开发 对话框的开发任务
  int _page = 1;

  @override
  FutureOr<List<ChatSession>> build() {
    return getSessionByPage();
  }

  Future<void> refresh(void Function()? onRefresh) async {
    state = await AsyncValue.guard(() async {
      try {
        return getSessionByPage();
      } finally {
        onRefresh?.call();
      }
    });
  }

  Future<void> loadMore(void Function()? onLoadMore) async {
    state = await AsyncValue.guard(() async {
      print(" 进行数据的请求  >> loadMore");
      try {
        return getSessionByPage(page: _page + 1);
      } finally {
        onLoadMore?.call();
      }
    });
  }

  // 获取第一页的对话框
  Future<List<ChatSession>> getSessionByPage({int page = 1}) async {
    return await Future.delayed(const Duration(seconds: 1), () {
      print(" 进行数据的请求 当前的page == ${page}");
      const pageSize = 20;
      var result = <ChatSession>[];
      for (var idx = (page - 1) * 20; idx < pageSize * page; idx++) {
        result.add(ChatSession(idx, "$idx >>> Session"));
      }
      _page = page;
      return result;
    });
  }
}

final chatSession2Provider = AsyncNotifierProvider<ChatSessionList2Provider, List<ChatSession>>(
        () => ChatSessionList2Provider());

class _TextAsyncNotifier2Provider extends ConsumerStatefulWidget {
  @override
  ConsumerState<ConsumerStatefulWidget> createState() {
    return __AsyncState();
  }
}

class __AsyncState extends ConsumerState<_TextAsyncNotifier2Provider> {
  final _refreshController = EasyRefreshController(
    controlFinishLoad: true,
    controlFinishRefresh: true,
  );

  final List<ChatSession> _session = [];

  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    ref.listen(chatSession2Provider, (previous, next) {
      if (next.value == null) return;
      setState(() {
        _session.addAll(next.value!);
      });
    });
    return ConstrainedBox(
        constraints: const BoxConstraints(
          minWidth: double.infinity, //宽度尽可能大
          minHeight: 200.0, //最小高度为50像素
          maxHeight: 200,
        ),
        child: EasyRefresh(
          controller: _refreshController,
          header: const ClassicHeader(),
          footer: const ClassicFooter(),
          onRefresh: () {
            final notifier = ref.read(chatSession2Provider.notifier);
            notifier.refresh(() {
              _refreshController.finishRefresh();
              Fluttertoast.showToast(msg: "上拉刷新--完成");
            });
          },
          onLoad: () async {
            print(" 进行数据的请求  >> onLoad >>> ");
            final notifier = ref.read(chatSession2Provider.notifier);
            notifier.loadMore(() {
              _refreshController.finishLoad();
              Fluttertoast.showToast(msg: "下拉加载--完成");
            });
            _refreshController.resetFooter();
          },
          child: ListView.builder(
              itemExtent: 50,
              itemCount: _session.length,
              itemBuilder: (BuildContext context, int index) {
                final item = _session[index];
                return Text(item.toString());
              }),
        ));
  }
}
